package com.gary.security.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.gary.core.action.BaseAction;
import com.gary.core.orm.query.DefaultQueryItem;
import com.gary.core.orm.query.NullQueryItem;
import com.gary.core.orm.query.QueryFilter;
import com.gary.core.util.BeanUtil;
import com.gary.core.util.JsonUtils;
import com.gary.security.model.MenuInfo;
import com.gary.security.repository.MenuRepository;


/**
 * menu action.
 *
 */
public class MenuAction extends BaseAction<MenuInfo> {
    /** * serial. */
    static final long serialVersionUID = 0L;

    /** * menu manager. */
    private transient MenuRepository menuReps = null;

    /** * menu list. */
    private List<MenuInfo> list;

    /** * id. */
    private long id;

    /** * parent id. */
    private long parentId;
    private long node;
    private String data;

    /** * @return success. */
    public String list() {
        this.list = menuReps.getAll();

        return SUCCESS;
    }

    /** * @return redirect. */
    public String save() {
        MenuInfo menu;

        if (id == 0L) {
            menu = new MenuInfo();
        } else {
            menu = menuReps.getById(id,true);
        }

        BeanUtil.copyProperties(model, menu);

        try {
            MenuInfo parent = menuReps.getById(parentId,true);
            menu.setParent(parent);
            menuReps.save(menu);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return "redirect";
    }

    /** * @return forward. */
    public String edit() {
        this.model = menuReps.getById(id,true);

        return "forward";
    }

    /** * @return redirect. */
    public String remove() {
    	menuReps.deleteById(id);

        return "redirect";
    }

    //
    /** * @param menuManager menu manager. */
    public void setMenuReps(MenuRepository menuReps) {
        this.menuReps = menuReps;
    }

    /** * @return menu list. */
    public List<MenuInfo> getList() {
        return list;
    }

    /** * @param id long. */
    public void setId(long id) {
        this.id = id;
    }

    /** * @param parentId long. */
    public void setParentId(long parentId) {
        this.parentId = parentId;
    }

    public void setNode(long node) {
        this.node = node;
    }

    public void setData(String data) {
        this.data = data;
    }

    // ====================================================

    /**
     * �?��性获得整棵树的数�?
     *
     * @throws Exception 异常
     */
    public void getAllTree() throws Exception {
        QueryFilter filter = new QueryFilter();
        filter.addOrderBy("e.theSort","asc").addOrderBy("e.id","desc");
        List<MenuInfo> list = menuReps.getAll(filter);

        JsonUtils.write(list,
            ServletActionContext.getResponse().getWriter(),
            getExcludesForAll(), getDatePattern());
    }

    /**
     * 根据传入参数，返回对应id分类的子分类，用于显示分类的树形结构.
     * 如果没有指定id的�?，则返回�?��根节�?
     *
     * @throws Exception 异常
     */
    public void getChildren() throws Exception {
        long parentId = node;
        List<MenuInfo> list = null;
        
        QueryFilter filter = new QueryFilter();
        filter.addOrderBy("e.theSort","asc").addOrderBy("e.id","desc");
        if (parentId == -1L) {
            filter.addQueryItem(new NullQueryItem("and","e.parent","is"));
        } else {
        	filter.addQueryItem(new DefaultQueryItem("and","e.parent.id",parentId));
        }
        
        list=menuReps.getAll(filter);

        JsonUtils.write(list,
            ServletActionContext.getResponse().getWriter(),
            getExcludesForChildren(), getDatePattern());
    }

    /**
     * 根据id获取�?��记录.
     *
     * @throws Exception 写入json可能出现异常
     */
    public void loadData() throws Exception {
        MenuInfo entity = menuReps.getById(id,false);

        if (entity != null) {
            List<MenuInfo> list = new ArrayList<MenuInfo>();
            list.add(entity);
            JsonUtils.write(list,
                ServletActionContext.getResponse().getWriter(),
                getExcludesForChildren(), getDatePattern());
        }
    }

    /**
     * 添加�?��分类.
     * 目前还不没有返回成功或�?错误信息
     * 校验方式，当输入的data参数不存在的时�?，直接返�?
     *
     * @throws Exception 异常
     */
    public void insertTree() throws Exception {
        MenuInfo node = JsonUtils.json2Bean(data, MenuInfo.class,
                getExcludesForChildren(), getDatePattern());

        MenuInfo entity = menuReps.getById(node.getId(),false);

        // 更新上级分类
        Long parentId = node.getParentId();

        if (parentId != null) {
            MenuInfo parent = menuReps.getById(parentId,true);
            node.setParent(parent);
        }

        if (entity == null) {
            // 添加
            // 只有在id = null的情况下，才执行insert，否则执行update
            node.setId(null);
            menuReps.save(node);
            entity = node;
        } else {
            // 修改
            entity.setName(node.getName());
            menuReps.save(entity);
        }

        ServletActionContext.getResponse().getWriter()
                            .print("{success:true,id:" + entity.getId()
            + "}");
    }

    /**
     * 根据id删除�?��分类，由于级联关系，会同时删除所有子分类.
     *
     * @throws Exception 异常
     */
    public void removeTree() throws Exception {
        if (id != -1L) {
        	menuReps.deleteById(id);
        }
    }

    /**
     * 保存排序结果.
     * 参数是JSONArray，保存了id列表，排序时候根据id列表修改theSort字段
     *
     * @throws Exception 异常
     */
    public void sortTree() throws Exception {
        List<MenuInfo> list = JsonUtils.json2List(data, MenuInfo.class,
                getExcludesForChildren(), getDatePattern());

        for (int i = 0; i < list.size(); i++) {
            MenuInfo node = list.get(i);
            String id = node.getId();
            Long parentId = node.getParentId();

            MenuInfo entity = menuReps.getById(id,true);

            if (entity != null) {
                MenuInfo parent = menuReps.getById(parentId,true);
                entity.setParent(parent);
                entity.setTheSort(i);
                menuReps.save(entity);
            }
        }
    }

    /**
     * updateTree.
     * 修改信息信息
     *
     * @throws Exception 异常
     */
    public void updateTree() throws Exception {
        MenuInfo menu = menuReps.getById(id,true);
        BeanUtil.copyProperties(model, menu);

        menuReps.save(menu);

        ServletActionContext.getResponse().getWriter()
                            .print("{success:true,info:\"success\"}");
    }

    /**
     * 迭代取得�?��节点时�?，使用的exclude设置.
     *
     * @return 不需要转化成json的属性列表，默认是空�?
     */
    public String[] getExcludesForAll() {
        return new String[] {"class", "root", "parent", "checked", "roles"};
    }

    /**
     * 只取得直接子节点时，使用的exclude设置.
     *
     * @return 不需要转换json的属性数�?
     */
    public String[] getExcludesForChildren() {
        return new String[] {
            "class", "root", "parent", "children", "checked", "roles"
        };
    }

    public String getDatePattern() {
        return "yyyy-MM-dd";
    }
}
